#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
import os
import re
from conf import CONFIG, settings
from logger import logger
from request import http
from core.verification.apply import PathApply


def _file(cve, file):
    """
    save file path

    :param cve: fiex cve number
    :param file: save path
    """
    file = os.path.join(file, cve)
    os.makedirs(file, exist_ok=True)
    file_name = (
        "fix-cve-"
        + str(sum([os.path.isfile(file+"/"+list_index)
              for list_index in os.listdir(file)]) + 1)
        + ".patch"
    )
    return os.path.join(file, file_name)


def _patch_url(url):
    download_rules = settings.configuration.get("download")
    if not download_rules:
        return url + ".patch"

    for replace in filter(lambda x: x.get("action") == "REPLACE", download_rules):
        if re.findall(replace.get("regex", ""), url):
            target_regex = replace.get("target", ["commit", "patch"])
            return re.sub(target_regex[0], target_regex[-1], url)

    for append in filter(lambda x: x.get("action") == "APPEND", download_rules):
        if re.findall(append.get("regex", ""), url):
            target_regex = append.get("target", [".patch"])
            return url + target_regex[-1]
    return None


def save_patch(patch_details=None, path=CONFIG.PATCH_SAVE_PATH, args=None):
    """
    Download and save the patch file
    :param patch_details: patch info
    :param path: patch path
    :param args: cve number
    :return: None
    """
    cve = args.cve_num
    commits = set()
    for patch in patch_details:
        for issue_info in patch.get("details", list()):
            for pr in issue_info["issue"].get("prs", list()):
                commits.update(pr.get("commits", []))
    if not args.packing:
        # download patch
        for url in commits:
            out_file = _file(cve=cve, file=path)
            patch_url = _patch_url(url=url) or url
            file = http.download(url=patch_url, out_fname=out_file)
            if not file:
                logger.error("Failed to download the file: %s" % patch_url)
        return None
    else:
        patch_url_state = {}
        for url in commits:
            out_file = _file(cve=cve, file=path)
            patch_url = _patch_url(url=url) or url
            file = http.download(url=patch_url, out_fname=out_file)
            if not file:
                logger.error("Failed to download the file: %s" % patch_url)
                patch_url_state[url] = "不适配"
            patch_apply = PathApply(rpm_name=args.rpm_name, patch_path=args.patch_path,
                                    source_path=args.source_path, branch_rpm=args.branch, cve_num=args.cve_num)
            stat = patch_apply.packing_source()
            patch_apply.clear_trash()
            patch_url_state[url] = stat
        return patch_url_state


__all__ = ("save_patch",)
